#include <iostream>
#include <fstream>
#include <cstring>
#include <ctime>
#include <cstdlib>
#include "ti.h"
#include "tplate.h"
#include "txtpara.h"
#include "regression.h"
using namespace std;

int main(int argc, char **argv)
{
    if (argc != 5)
    {
        cout << "Usage:\n" << argv[0] <<
            " param_file training_image_file template_file paramfile"
            << endl;
        return 0;
    }
    train_grid_cont *ti = new train_grid_cont;
    read_image_cont(ti, argv[2]);
    float rate = 1;
    rate = getparaFLOAT("rate", argv[1]);
    tplate tp;
    // Read the training image to the trianing grid
    load_template(&tp, argv[3]);
    int length = ti->length;
    int width = ti->width;
    //Randomly select 10% of the points
    srand(time(NULL));
    int nr_sample = length * width * rate;
    float *data = new float[2 * tp.tpsize * nr_sample];
    float *ydata = new float[tp.tpsize * nr_sample];
    float *theta = new float[(3 + 1) * tp.tpsize];    //w0, w1, and sigma
    /*memset(data, 0, sizeof(float) * 2 * tp.tpsize * nr_sample); */
    for (int xpos = 0; xpos < nr_sample * 2; xpos++)
    {
        for (int ypos = 0; ypos < tp.tpsize; ypos++)
            data[xpos * tp.tpsize + ypos] = 0;
    }
    //The first column remains 0
    for (int i = 0; i < nr_sample; i++)
    {
        int xpos = rand() % length;
        int ypos = rand() % width;
        bool out_bound = false;
        for (int tpos = 0; tpos < tp.tpsize; tpos++)
        {
            int x_ = xpos + tp.pos[2 * tpos];
            int y_ = ypos + tp.pos[2 * tpos + 1];
            if ((x_ < 0) || (x_ >= length))
            {
                out_bound = true;
                break;
            }
            if ((y_ < 0) || (y_ >= width))
            {
                out_bound = true;
                break;
            }
            data[tpos * nr_sample * 2 + i * 2 + 0] = 1;
            data[tpos * nr_sample * 2 + i * 2 + 1] = ti->data[x_ * width + y_]; 
            ydata[nr_sample * tpos + i] = ti->data[xpos * width + ypos]; 
        }
        if (out_bound == true)
            i -= 1;
    }
    ofstream param;
    param.open(argv[4]);
    param << 4 << " ";            //the size of each theta
    param << tp.tpsize << endl;    //the total number os thetas
    for (int tpos = 0; tpos < tp.tpsize; tpos++)
    {
        //Calculate regression coefficient
        regression(data + 2 * nr_sample * tpos, 2, nr_sample,
                   ydata + nr_sample * tpos, 1, theta + 4 * tpos);
        for (int i = 0; i < 4; i++)
        {
            param << theta[4 * tpos + i] << " ";    // the content of each theta
        }
        param << endl;
        //if(theta[4*tpos+3]>0.01) break;
    }
    param.close();
    return 0;
}
